package service

import (
	"context"
	coreV1 "k8s.io/api/core/v1"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"strconv"
)

func GetServiceList(clientSet *kubernetes.Clientset, namespaceName string) (serviceList *coreV1.ServiceList, err error) {
	serviceList, err = clientSet.CoreV1().Services(namespaceName).List(context.TODO(), metaV1.ListOptions{})
	if err != nil {
		return serviceList, err
	}
	return serviceList, nil
}

func CreateService(clientSet *kubernetes.Clientset, request CreateServiceRequest) (serviceInfo *coreV1.Service, err error) {
	servicePort := explainServicePort(request.PortList)
	service := &coreV1.Service{
		ObjectMeta: metaV1.ObjectMeta{
			Name:   request.Name,
			Labels: request.BandTag,
		},
		Spec: coreV1.ServiceSpec{
			Type:     coreV1.ServiceTypeNodePort,
			Selector: request.BandTag,
			Ports:    servicePort,
		},
	}
	serviceInfo, err = clientSet.CoreV1().Services(request.NamespaceName).Create(context.TODO(), service, metaV1.CreateOptions{})
	return serviceInfo, nil
}

func explainServicePort(portList map[int32]int32) (response []coreV1.ServicePort) {
	for portIn, portOut := range portList {
		containerPort := coreV1.ServicePort{
			Name:     "port" + strconv.FormatInt(int64(portIn), 10),
			Port:     portIn,
			Protocol: coreV1.ProtocolTCP,
			NodePort: portOut,
		}
		response = append(response, containerPort)
	}

	return response
}

func GetService(clientSet *kubernetes.Clientset, namespaceName string, serviceName string) (serviceInfo *coreV1.Service, err error) {
	serviceInfo, err = clientSet.CoreV1().Services(namespaceName).Get(context.TODO(), serviceName, metaV1.GetOptions{})
	if err != nil {
		return serviceInfo, err
	}
	return serviceInfo, nil
}

func ApplyServiceByPort(clientSet *kubernetes.Clientset, request ApplyServiceRequest) (serviceInfo *coreV1.Service, err error) {
	servicePort := explainServicePort(request.PortList)
	service, err := clientSet.CoreV1().Services(request.NamespaceName).Get(context.TODO(), request.Name, metaV1.GetOptions{})
	if err != nil {
		return serviceInfo, err
	}

	service.Spec.Ports = servicePort
	service.ObjectMeta.Labels = request.BandTag
	service.Spec.Selector = request.BandTag
	serviceInfo, err = clientSet.CoreV1().Services(request.NamespaceName).Update(context.TODO(), service, metaV1.UpdateOptions{})
	if err != nil {
		return serviceInfo, err
	}

	return serviceInfo, nil
}

func DeleteService(clientSet *kubernetes.Clientset, request DeleteServiceRequest) (err error) {
	err = clientSet.CoreV1().Services(request.NamespaceName).Delete(context.TODO(), request.ServiceName, metaV1.DeleteOptions{})
	if err != nil {
		return err
	}
	return nil
}
